package com.faxsun.profile.core.dao;


import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.broadleafcommerce.profile.core.dao.CustomerDaoImpl;
import org.broadleafcommerce.profile.core.domain.Customer;
import org.hibernate.jpa.QueryHints;

import javax.persistence.Query;
import javax.persistence.TypedQuery;
import java.util.List;


public class FSCustomerDaoImpl extends CustomerDaoImpl implements FSCustomerDao {

    private static final Log LOG = LogFactory.getLog(FSCustomerDaoImpl.class);

    public boolean check3thCustomerByUid(String uid) {
        Query query = em
            .createQuery("SELECT uid FROM com.faxsun.profile.core.domain.FSCustomer fsCustomer"
                + " where fsCustomer.uid=:uid");
        query.setParameter("uid", uid);
        query.setHint(QueryHints.HINT_CACHEABLE, true);
        query.setHint(QueryHints.HINT_CACHE_REGION, "query.FSCustomer");

        @SuppressWarnings("unchecked")
        List<String> results = query.getResultList();

        return results == null || results.isEmpty() ? false : true;
    }

    @SuppressWarnings("unchecked")
    private List<Long> readCustomersBy3thUid(String uid) {
        Query query = em
            .createQuery("SELECT id FROM com.faxsun.profile.core.domain.FSCustomer fsCustomer"
                + " where fsCustomer.uid=:uid");
        query.setParameter("uid", uid);
        query.setHint(QueryHints.HINT_CACHEABLE, true);
        query.setHint(QueryHints.HINT_CACHE_REGION, "query.FSCustomer");
        return query.getResultList();
    }

    @Override
    public Long readCustomerIdBy3thUid(String uid) {
        List<Long> ids = readCustomersBy3thUid(uid);
        Long id = ids == null || ids.isEmpty() ? 0 : ids.get(0);
        return id;
    }

    @Override
    public boolean isMobileBinded(String mobile) {

        Query query = em.createQuery("SELECT fsCustomer FROM org.broadleafcommerce.profile.core.domain.Customer fsCustomer"
                + " where fsCustomer.mobile=:mobile and fsCustomer.deactivated=false"
        );
        query.setParameter("mobile", mobile);
        query.setHint(QueryHints.HINT_CACHEABLE, true);
        query.setHint(QueryHints.HINT_CACHE_REGION, "query.FSCustomer");

        @SuppressWarnings("unchecked")
        List<Customer> results = query.getResultList();

        return results.size() >= 1;
    }

    @Override
    public Customer readCustomerByMobile(String mobile) {
        Query query = em.createQuery("SELECT fsCustomer FROM org.broadleafcommerce.profile.core.domain.Customer fsCustomer"
                + " where fsCustomer.mobile=:mobile and fsCustomer.isVerified=true and fsCustomer.deactivated=false"
        );
        query.setParameter("mobile", mobile);
        query.setHint(QueryHints.HINT_CACHEABLE, true);
        query.setHint(QueryHints.HINT_CACHE_REGION, "query.FSCustomer");

        @SuppressWarnings("unchecked")
        List<Customer> results = query.getResultList();

        Customer customer = null;

        if (results.size() == 0) {
        } else if (results.size() == 1) {
            customer = results.get(0);
        } else {
            LOG.error("Mobile phone is registered more than once. And the mobile is " + mobile);
        }
        return customer;
    }

    @Override
    public Customer readCustomerByEmail(String emailAddress) {
        Query query = em.createQuery("SELECT fsCustomer FROM org.broadleafcommerce.profile.core.domain.Customer fsCustomer"
                + " where fsCustomer.emailAddress=:emailAddress and fsCustomer.deactivated=false"
        );
        query.setParameter("emailAddress", emailAddress);
        query.setHint(QueryHints.HINT_CACHEABLE, true);
        query.setHint(QueryHints.HINT_CACHE_REGION, "query.FSCustomer");

        @SuppressWarnings("unchecked")
        List<Customer> customers = query.getResultList();

        if (customers.size() > 1) {
            LOG.error("emailAddress is registered more than once. And the emailAddress is " + emailAddress);
        }
        return customers == null || customers.isEmpty() ? null : customers.get(0);
    }

    @Override
    public Customer readCustomerByUsername(String username, Boolean cacheable) {
        Query query = em.createQuery("SELECT fsCustomer FROM org.broadleafcommerce.profile.core.domain.Customer fsCustomer"
                + " where fsCustomer.username=:username and fsCustomer.deactivated=false"
        );
        query.setParameter("username", username);
        query.setHint(QueryHints.HINT_CACHEABLE, cacheable);
        query.setHint(QueryHints.HINT_CACHE_REGION, "query.FSCustomer");

        @SuppressWarnings("unchecked")
        List<Customer> customers = query.getResultList();

        if (customers.size() > 1) {
            LOG.error("username is registered more than once. And the username is " + username);
        }
        return customers == null || customers.isEmpty() ? null : customers.get(0);
    }

    @Override
    public Customer readCustomerByReferralCode(String referralCode) {
        TypedQuery<Customer> query = em.createQuery(
            "SELECT fsCustomer FROM org.broadleafcommerce.profile.core.domain.Customer fsCustomer"
            + " WHERE fsCustomer.referralCode = :referralCode", Customer.class);
        query.setParameter("referralCode", referralCode);
        query.setHint(QueryHints.HINT_CACHEABLE, true);
        query.setHint(QueryHints.HINT_CACHE_REGION, "query.FSCustomer");
        return query.getSingleResult();
    }

	@Override
	public int countCustomerByEmail(String email) {
		 Query query = em.createQuery("SELECT fsCustomer FROM org.broadleafcommerce.profile.core.domain.Customer fsCustomer"
	                + " where fsCustomer.emailAddress=:emailAddress and fsCustomer.deactivated=false"
	        );
	        query.setParameter("emailAddress", email);
	        query.setHint(QueryHints.HINT_CACHEABLE, true);
	        query.setHint(QueryHints.HINT_CACHE_REGION, "query.FSCustomer");

	        @SuppressWarnings("unchecked")
	        List<Customer> customers = query.getResultList();

	        return customers.size();
	}

}
